package com.ecoolex.ying.space.core.manager;

import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.util.BizAssert;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.framework.modularize.api.auth.user.ConsumerMember;
import com.ecoolex.framework.modularize.api.auth.user.ConsumerMemberManager;
import com.ecoolex.ying.space.core.dao.UserFavoriteItemsDAO;
import com.ecoolex.ying.space.entity.UserFavorite;
import com.ecoolex.ying.space.entity.UserFavoriteItemsExample;
import com.ecoolex.ying.space.entity.UserFavoriteItems;
import com.ecoolex.ying.space.entity.UserFavoriteItems.Column;
import com.ecoolex.ying.space.entity.UserWorks;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Instant;
import java.util.Date;
import java.util.List;


@Service
public class UserFavoriteItemsManager {

    @Autowired
    private UserFavoriteItemsDAO dao;

    @Autowired
    private ConsumerMemberManager consumerMemberManager;

    @Autowired
    private UserWorksManager userWorksManager;

    @Autowired
    private UserWorksStatisticalManager userWorksStatisticalManager;

    public long countByFavoriteId(Integer id) {
        UserFavoriteItemsExample example = new UserFavoriteItemsExample();
        UserFavoriteItemsExample.Criteria criteria = example.createCriteria();
        criteria.andFavoriteIdEqualTo(id);
        criteria.andLogicalDeleted(UserFavoriteItems.NOT_DELETED);
        return dao.countByExample(example);
    }

    public UserFavoriteItems getByUserIdAndContentId(Integer userId, Integer contentId) {
        UserFavoriteItemsExample example = new UserFavoriteItemsExample();
        example.createCriteria().andLogicalDeleted(UserFavoriteItems.NOT_DELETED).andUserIdEqualTo(
            userId).andContentIdEqualTo(contentId);
        return dao.selectOneByExample(example);
    }

    public UserFavoriteItems getByUserIdAndFavoriteItemId(Integer userId, Integer favoriteItemId) {
        UserFavoriteItemsExample example = new UserFavoriteItemsExample();
        example.createCriteria().andLogicalDeleted(UserFavoriteItems.NOT_DELETED).andUserIdEqualTo(
            userId).andFavoriteItemIdEqualTo(favoriteItemId);
        return dao.selectOneByExample(example);
    }

    public Pagination<UserFavoriteItems> queryUserFavoriteItemsByFavoriteId(Integer favoriteId, Page page) {
        UserFavoriteItemsExample example = new UserFavoriteItemsExample();
        UserFavoriteItemsExample.Criteria criteria = example.createCriteria();
        criteria.andDeletedEqualTo(UserFavorite.NOT_DELETED);
        criteria.andFavoriteIdEqualTo(favoriteId);

        example.orderBy(Column.createTime.desc());
        example.setOffset(page.getFirstIndex());
        example.setRows(page.getPageSize());
        return Pagination.create(page, dao.countByExample(example), () -> dao.selectByExample(example));
    }

    public Pagination<UserFavoriteItems> queryMyUserFavoriteItems(Integer userId, Page page) {
        UserFavoriteItemsExample example = new UserFavoriteItemsExample();
        UserFavoriteItemsExample.Criteria criteria = example.createCriteria();
        criteria.andUserIdEqualTo(userId).andDeletedEqualTo(UserFavoriteItems.NOT_DELETED);

        example.orderBy(Column.createTime.desc());
        example.setOffset(page.getFirstIndex());
        example.setRows(page.getPageSize());
        return Pagination.create(page, dao.countByExample(example), () -> dao.selectByExample(example));
    }

    public long queryMyUserFavoriteItemsCount(Integer userId) {
        UserFavoriteItemsExample example = new UserFavoriteItemsExample();
        UserFavoriteItemsExample.Criteria criteria = example.createCriteria();
        criteria.andUserIdEqualTo(userId).andDeletedEqualTo(UserFavoriteItems.NOT_DELETED);
        return dao.countByExample(example);
    }

    public Pagination<UserFavoriteItems> queryOtherUserFavoriteItems(Integer userId, Page page) {
        return Pagination.create(page, dao.countByUserId(userId), () -> dao.queryByUserId(userId, page));
    }

    public long queryOtherUserFavoriteItemsCount(Integer userId) {
        return dao.countByUserId(userId);
    }

    public List<UserFavoriteItems> getByFavoriteIdAndContentIdAndUserId(UserFavoriteItems record) {
        UserFavoriteItemsExample example = new UserFavoriteItemsExample();
        UserFavoriteItemsExample.Criteria criteria = example.createCriteria();
        criteria.andUserIdEqualTo(record.getUserId()).andFavoriteIdEqualTo(record.getFavoriteId()).andContentIdEqualTo(
            record.getContentId()).andDeletedEqualTo(UserFavoriteItems.NOT_DELETED);
        return dao.selectByExample(example);
    }

    @Transactional
    public UserFavoriteItems add(UserFavoriteItems record, String createUser) {
        BizAssert.isTrue(Check.notNullAndGteZero(record.getFavoriteId()), ResultCode.VERIFY.build(1), "收藏夹id为空");
        BizAssert.isTrue(Check.notNullAndGteZero(record.getContentId()), ResultCode.VERIFY.build(2), "收藏内容id为空");
        BizAssert.isTrue(Check.notNullAndGteZero(record.getUserId()), ResultCode.VERIFY.build(3), "用户id为空");
        List<UserFavoriteItems> userFavoriteItems = getByFavoriteIdAndContentIdAndUserId(record);
        if (Check.isNullOrEmpty(userFavoriteItems)) {
            UserWorks userWorks = userWorksManager.getById(record.getContentId());
            BizAssert.isTrue(Check.notNull(userWorks), ResultCode.VERIFY.build(4), "收藏的内容不存在");
            record.setContentAuthorUserId(userWorks.getUserId());
            record.setDeleted(UserFavoriteItems.NOT_DELETED);
            record.setCreateUser(createUser);
            record.setCreateTime(Date.from(Instant.now()));
            record.setUpdateUser(createUser);
            record.setUpdateTime(Date.from(Instant.now()));

            dao.insert(record);
            // 作品收藏统计
            userWorksStatisticalManager.collectCount(record.getContentId(), createUser);
        }
        return record;
    }

    @Transactional
    public void delete(UserFavoriteItems record, String updateUser) {
        record.setDeleted(UserFavoriteItems.IS_DELETED);
        record.setUpdateUser(updateUser);
        record.setUpdateTime(Date.from(Instant.now()));
        dao.updateByPrimaryKeySelective(record,
            UserFavoriteItems.Column.deleted,
            UserFavoriteItems.Column.updateUser,
            UserFavoriteItems.Column.updateTime);
        // 取消收藏统计
        userWorksStatisticalManager.cancelCollectCount(record.getContentId(), updateUser);
    }

    public ConsumerMember getContentAuthor(Integer userId) {
        return consumerMemberManager.getByUserId(userId);
    }

    public UserWorks getUserWorks(Integer id) {
        return userWorksManager.getById(id);
    }

}